import katex from 'katex'
/* eslint-disable */
function replaceErrorFormula(html) {
  if (typeof html === 'string') {
    html = html.replace(/\\&quot;\\\\overparen/g, '\\\\overparen') //去除莫名产生的空格
    html = html.replace(/\\\\overparen/g, '\\overgroup')
  }
  return html
}
//公式标签渲染
function overwriteTagTex(html) {
  if (typeof html !== 'string') return html
  html = replaceErrorFormula(html)
  //过滤未格式化公式空行
  //去除公式两端空格
  html = html.replace(/((&nbsp;)|\s)*<tex /g, '<tex ')
  html = html.replace(/\/tex>((&nbsp;)|\s)* /g, '/tex>')
  //去除公式两端空行
  html = html.replace(/(<p>((&nbsp;)|\s)*<\/p>\r*\n*)*(<p>)?<tex\s/g, '$4<tex ')
  html = html.replace(
    /<\/tex>(<\/p>)?(\r*\n*<p>((&nbsp;)|\s)*<\/p>)*/g,
    '</tex>$1'
  )

  //可以转do-while + 正则matchAll提取
  let matches = html.match(/<tex\/?.+?tex>/gi)
  if (matches?.length) {
    matches.forEach(latexTag => {
      let latex = ''
      //latex提取
      let latexArr = latexTag.match(/data-latex="(.*?)"/g)
      if (latexArr) {
        latex = latexArr[0]
        latex = latex.replace(/^(data-latex=")|"$/g, '')
      }
      //注意：有些公式会把'\'反斜杠转成'&'字符，kate就无法正常渲染公式
      latex = latex.replace(/\s*&minus;/g, ' - ')
      latex = latex.replace(/\s*&eta;/g, '\\eta')
      latex = latex.replace(/\s*&times;/g, '\\times')
      latex = latex.replace(/\s*&sdot;/g, '\\sdot')
      latex = latex.replace(/\s*&Omega;/g, '\\Omega')
      latex = latex.replace(/\s*&Delta;/g, ' Delta')
      latex = latex.replace(/\s*&lt;/g, ' \\lt')
      latex = latex.replace(/\s*&gt;/g, ' \\gt')
      latex = latex.replace(/&rsquo;/g, ' ’ ')
      latex = latex.replace(/&#39;/g, " ' ")
      latex = latex.replace(/\s*&amp;\s*(?!\w)/g, ' & ')
      latex = latex.replace(/&amp;/g, ' & ')

      //katex渲染，todo：加公共样式控制
      //displayModel:false, 如果是多行公式，正则添加katex-display进行多行显示
      let katexStr
      try {
        katexStr = katex.renderToString(latex, {
          output: 'html',
          strict: false
        })
      } catch (err) {
        // 捕获错误避免网站因错误所有操作失灵，进行打印并且告知用户公式错误解析失败
        katexStr = ''
      }
      if (/\\\\/g.test(latex)) {
        //段标签渲染
        //添加空行，并去除两侧p标签
        katexStr = katexStr.replace(
          'class="katex-html"',
          'class="katex-html katex-display"'
        )
        html = html.replace(
          `${latexTag}`,
          katexStr
            ? `&nbsp;<tag-tex class="tag-tex tag-tex-paragraph" data-latex="${latex}">` +
                katexStr +
                `</tag-tex>&nbsp;`
            : ''
        )
      } else {
        //行标签渲染
        html = html.replace(
          `${latexTag}`,
          katexStr
            ? `&nbsp;<tag-tex class="tag-tex tag-tex-row" data-latex="${latex}">` +
                katexStr +
                `</tag-tex>&nbsp;`
            : ''
        )
      }
    })
  }
  return html
}
/**
 * @description 填空位标签渲染，blk => tag-blk
 * @param content 需要修改的富文本
 * @param type 修改的类型，默认为1，可选值 1，2。1 表示默认的显示状态，2表示编辑题目的显示状态，需要保留题号，长度等显示内容。
 * @returns {string} 富文本
 */
function overwriteTagBlk(content, type = 1) {
  if (typeof content !== 'string') return content
  content = content.replace(/((&nbsp;)|\s)*<blk /g, '<blk ')
  content = content.replace(/\/blk>((&nbsp;)|\s)* /g, '/blk>')

  let matches = content.match(/<blk\/?.+?blk>/gi)
  if (matches?.length) {
    matches.forEach((blkTag, index) => {
      let mlen = 3 // 填空位长度，默认是3
      let mlenMatch = blkTag.match(/mlen="(.*?)"/)
      if (mlenMatch) {
        mlen = parseFloat(mlenMatch[1])
        if (!mlen || mlen < 3) mlen = 3 //最小值是3
        if (type !== 2) {
          // 非编辑模式下限制最大值为10
          if (mlen > 10) mlen = 10 // 最大值是10
        }
      }
      let styleType = '' // 填空位样式，默认不是下划线
      let styleMatch = blkTag.match(/mstyle="(.*?)"/)
      if (styleMatch?.[1] === 'underline') {
        styleType = styleMatch[1]
      }
      let newBlkTag = ''

      let spanStr = ''
      new Array(Math.round(mlen / 2) || 4).fill('').forEach(() => {
        spanStr += '&nbsp;&nbsp;'
      })

      if (type === 1) {
        let style = `white-space:pre;width:${mlen}em;display:inline-block;`
        if (styleType === 'underline') {
          style = style + 'border-bottom:1px solid #333;'
        }
        newBlkTag = `&nbsp;<tag-blk mlen="${mlen}" ${
          styleMatch?.[0] || ''
        } data-index="${
          index + 1
        }" style="${style}">${spanStr}${spanStr}</tag-blk>&nbsp;`
      } else {
        let style = ``
        let str = ``
        if (styleType === 'underline') {
          style =
            'border:1px dashed #eee;text-decoration: underline;color:rgb(52, 105, 242)' +
            style
          str = `${spanStr}${mlen}${spanStr}`
        } else {
          style =
            'border: 1px dashed rgb(52, 105, 242);color:rgb(52, 105, 242)' +
            style
          str = `${spanStr}${mlen}${spanStr}`
        }

        newBlkTag = `&nbsp;<tag-blk mlen="${mlen}" ${
          styleMatch?.[0] || ''
        } data-index="${
          index + 1
        }" style="${style}" data-mce-style="${style}">${str}</tag-blk>&nbsp;`
      }

      content = content.replace(blkTag, newBlkTag)
    })
  }
  return content
}
// 设置图片源
function overwriteImgSrc(content) {
  if (typeof content !== 'string') return content
  const domain = import.meta.env.VITE_APP_IMG_PATH
  var imgReg = /<img.*?(?:>|\/>)/gi
  var srcReg = /src=[\'\"]?([^\'\"]*)[\'\"]?/i
  var arr = content.match(imgReg) // arr 为包含所有img标签的数组
  arr?.forEach(item => {
    var srcMatch = item.match(srcReg)
    if (srcMatch?.[1]) {
      let src = srcMatch[1]
      if (src.indexOf('http') !== 0) {
        src = domain + src
      }
      let str = item.replace(srcMatch[1], src)
      content = content.replace(item, str)
    }
  })
  return content
}

// 着重点处理
function overwriteEmphasize(html) {
  if (typeof html !== 'string') return html
  let matches = html.match(/<e>.+?\/e>/gi)
  if (matches?.length) {
    matches.forEach(value => {
      let str = ''
      let v = value.replace('<e>', '').replace('</e>', '')
      let tex = v.match(/<tag-tex\/?.+?tag-tex>/)
      if (tex?.length) {
        return
      }
      let index = 0
      while (v.length && index < 10000) {
        index++
        let matchWord = false
        let stashWord = ['&nbsp;']
        stashWord.forEach(key => {
          if (v.indexOf(key) === 0) {
            matchWord = true
            v = v.replace(key, '')
            str = str + key
          }
        })
        if (matchWord) {
          continue
        }
        let blk = v.match(/<tag-blk\/?.+?tag-blk>/)
        if (blk?.index === 0) {
          v = v.replace(blk[0], '')
          str = str + blk[0]
          continue
        }
        let tex = v.match(/<tag-tex\/?.+?tag-tex>/)
        if (tex?.index === 0) {
          v = v.replace(tex[0], '')
          str = str + tex[0]
          continue
        }
        let m = v.match(/<[^>]+>/)
        if (m?.index === 0) {
          // 闭合标签
          if (m.indexOf('/>') + 2 === m[0].length) {
            v = v.replace(m[0], '')
            str = str + m[0]
            continue
          }
        }
        str = str + `<e>${v[0]}</e>`
        v = v.slice(1)
      }
      html = html.replace(value, str)
    })
  }
  return html
}
const overwritePTagStyle = html => {
  if (typeof html !== 'string') return html
  let divMatches = html.match(/<div.*?>/gi)
  if (divMatches?.length) {
    divMatches.forEach(match => {
      // let latex = "";
      let matchArr = match.match(/align="(.*?)"/g)
      let align = matchArr?.[0] || ''

      html = html.replace(match, `<p ${align}>`)
    })
  }
  let spanMatches = html.match(/<span.*?>/gi)
  if (spanMatches?.length) {
    spanMatches.forEach(match => {
      html = html.replace(match, `<span >`)
    })
  }

  let matches = html.match(/<p.*?>/gi)
  if (matches?.length) {
    matches.forEach(match => {
      // let latex = "";
      let matchArr = match.match(/align="(.*?)"/g)
      let align = matchArr?.[0] || ''

      html = html.replace(match, `<p ${align}>`)
    })
  }

  return html
}

/**
 *
 * @param {string} str 需要修改的富文本
 * @param {number} type tagBlk 修改的类型，默认为1，可选值 1，2。1 表示默认的显示状态，2表示编辑题目的显示状态，需要保留题号，长度等显示内容。
 * @returns {string} 富文本
 */
export const katexSanitize = (str, type = 1) => {
  let v = str

  //去除换行
  v = v.replace(/[\r\n]/g, ' ')
  v = v.replace(/<br\/>/gi, ' ')
  v = v.replace(/<br>/gi, ' ')

  v = overwriteImgSrc(v)
  v = overwritePTagStyle(v)
  v = overwriteTagBlk(v, type)
  v = overwriteTagTex(v)
  if (type === 1) {
    v = overwriteEmphasize(v)
  }
  return v
}
